# -*- coding: utf-8 -*-
"""
配置服务层

负责系统配置相关的业务逻辑处理
"""
import json
import base64
from typing import Dict, Any, Optional, List, Union
from app.repositories.config_repository import ConfigRepository


class ConfigService:
    """配置服务类"""
    
    def __init__(self):
        self.config_repo = ConfigRepository()
        self._config_cache: Dict[str, Any] = {}
        self._cache_loaded = False
        
        # 简单加密密钥（生产环境应使用更安全的方式）
        self._encrypt_key = "config_encrypt_key_change_me"
    
    def get_config(self, config_key: str, default_value: Any = None) -> Any:
        """获取配置值"""
        # 如果缓存未加载，先加载缓存
        if not self._cache_loaded:
            self._load_cache()
        
        # 从缓存中获取配置
        if config_key in self._config_cache:
            return self._config_cache[config_key]
        
        # 从数据库获取配置
        config = self.config_repo.get_config_by_key(config_key)
        if not config:
            return default_value
        
        # 解析配置值
        value = self._parse_config_value(config)
        
        # 更新缓存
        self._config_cache[config_key] = value
        
        return value
    
    def get_config_group(self, group_name: str) -> Dict[str, Any]:
        """获取配置分组的所有配置"""
        configs = self.config_repo.get_configs_by_group(group_name)
        result = {}
        
        for config in configs:
            key = config['config_key']
            # 移除分组前缀，只保留子键名
            if '.' in key:
                sub_key = key.split('.', 1)[1]  # 取第一个点后的部分
            else:
                sub_key = key
            
            result[sub_key] = self._parse_config_value(config)
        
        return result
    
    def get_wechat_config(self) -> Dict[str, Any]:
        """获取微信配置"""
        return {
            'app_id': self.get_config('wechat.miniprogram.app_id', 'your_app_id'),
            'app_secret': self.get_config('wechat.miniprogram.app_secret', 'your_app_secret'),
            'api_base': self.get_config('wechat.api_base_url', 'https://api.weixin.qq.com')
        }
    
    def set_wechat_config(self, app_id: str, app_secret: str) -> bool:
        """设置微信配置"""
        try:
            self.update_config('wechat.miniprogram.app_id', app_id)
            self.update_config('wechat.miniprogram.app_secret', app_secret)
            return True
        except Exception as e:
            print(f"设置微信配置失败: {e}")
            return False
    
    def get_jwt_config(self) -> Dict[str, Any]:
        """获取JWT配置"""
        return {
            'secret_key': self.get_config('jwt.secret_key', 'your_jwt_secret_key'),
            'algorithm': self.get_config('jwt.algorithm', 'HS256'),
            'access_token_expire_minutes': self.get_config('jwt.access_token_expire_minutes', 10080),
            'refresh_token_expire_days': self.get_config('jwt.refresh_token_expire_days', 30)
        }
    
    def get_redis_config(self) -> Dict[str, Any]:
        """获取Redis配置"""
        return {
            'host': self.get_config('redis.host', 'localhost'),
            'port': self.get_config('redis.port', 6379),
            'db': self.get_config('redis.db', 0),
            'password': self.get_config('redis.password', '')
        }
    
    def get_business_config(self) -> Dict[str, Any]:
        """获取业务配置"""
        return {
            'default_page_size': self.get_config('business.default_page_size', 20),
            'max_page_size': self.get_config('business.max_page_size', 100),
            'session_timeout': self.get_config('business.session_timeout', 7200)
        }
    
    def update_config(self, config_key: str, config_value: Any, updated_by: Optional[str] = None) -> bool:
        """更新配置"""
        # 转换值为字符串
        if isinstance(config_value, (dict, list)):
            value_str = json.dumps(config_value, ensure_ascii=False)
        else:
            value_str = str(config_value)
        
        # 更新数据库
        success = self.config_repo.update_config_value(config_key, value_str, updated_by)
        
        if success:
            # 更新缓存
            config = self.config_repo.get_config_by_key(config_key)
            if config:
                self._config_cache[config_key] = self._parse_config_value(config)
        
        return success
    
    def batch_update_configs(self, configs: List[Dict[str, Any]], updated_by: Optional[str] = None) -> bool:
        """批量更新配置"""
        success = self.config_repo.batch_update_configs(configs, updated_by)
        
        if success:
            # 重新加载缓存
            self._load_cache()
        
        return success
    
    def create_config(self, config_data: Dict[str, Any]) -> Optional[str]:
        """创建新配置"""
        config_id = self.config_repo.create_config(config_data)
        
        if config_id:
            # 重新加载缓存
            self._load_cache()
        
        return config_id
    
    def get_all_configs_by_group(self) -> Dict[str, List[Dict[str, Any]]]:
        """获取按分组组织的所有配置"""
        all_configs = self.config_repo.get_all_configs()
        grouped_configs = {}
        
        for config in all_configs:
            group = config['config_group']
            if group not in grouped_configs:
                grouped_configs[group] = []
            
            # 不返回敏感信息
            config_info = {
                'config_key': config['config_key'],
                'config_value': '***' if config['is_encrypted'] else config['config_value'],
                'config_type': config['config_type'],
                'config_desc': config['config_desc'],
                'is_encrypted': config['is_encrypted'],
                'is_system': config['is_system']
            }
            grouped_configs[group].append(config_info)
        
        return grouped_configs
    
    def refresh_cache(self) -> bool:
        """刷新配置缓存"""
        try:
            self._load_cache()
            return True
        except Exception as e:
            print(f"刷新配置缓存失败: {e}")
            return False
    
    def _load_cache(self):
        """加载配置到缓存"""
        try:
            all_configs = self.config_repo.get_all_configs()
            self._config_cache.clear()
            
            for config in all_configs:
                key = config['config_key']
                value = self._parse_config_value(config)
                self._config_cache[key] = value
            
            self._cache_loaded = True
            print(f"配置缓存加载成功，共加载 {len(self._config_cache)} 个配置项")
            
        except Exception as e:
            print(f"加载配置缓存失败: {e}")
            self._cache_loaded = False
    
    def _parse_config_value(self, config: Dict[str, Any]) -> Any:
        """解析配置值"""
        config_type = config.get('config_type', 'string')
        config_value = config.get('config_value', '')
        is_encrypted = config.get('is_encrypted', 0)
        
        # 如果是加密的，先解密
        if is_encrypted:
            config_value = self._decrypt_value(config_value)
        
        # 根据类型转换值
        try:
            if config_type == 'int':
                return int(config_value) if config_value else 0
            elif config_type == 'float':
                return float(config_value) if config_value else 0.0
            elif config_type == 'bool':
                return str(config_value).lower() in ('true', '1', 'yes', 'on')
            elif config_type == 'json':
                return json.loads(config_value) if config_value else {}
            else:  # string
                return config_value
        except (ValueError, json.JSONDecodeError) as e:
            print(f"解析配置值失败 {config['config_key']}: {e}")
            return config_value
    
    def _encrypt_value(self, value: str) -> str:
        """加密配置值（简单实现）"""
        try:
            encoded = base64.b64encode(value.encode('utf-8')).decode('utf-8')
            return encoded
        except Exception:
            return value
    
    def _decrypt_value(self, encrypted_value: str) -> str:
        """解密配置值（简单实现）"""
        try:
            decoded = base64.b64decode(encrypted_value.encode('utf-8')).decode('utf-8')
            return decoded
        except Exception:
            return encrypted_value


# 全局配置服务实例
config_service = ConfigService() 